package com.ysd.lis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.ysd.common.Result;
import com.ysd.lis.entity.*;
import com.ysd.lis.mapper.pub.PubReportMapper;
import com.ysd.lis.mapper.sys.SysMenuMapper;
import com.ysd.lis.mapper.sys.SysModuleMapper;
import com.ysd.lis.mapper.sys.SysRoleMenuMapper;
import com.ysd.lis.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysd.lis.vo.ModuleAndMenuTreeVo;
import com.ysd.lis.vo.ModuleAndPointTreeVo;
import com.ysd.util.IncrementalNumberGenerator;
import com.ysd.util.RedisUserManager;
import com.ysd.util.ToolsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static java.awt.SystemColor.menu;

/**
 * <p>
 * cold_chain.t_menu 服务实现类
 * </p>
 *
 * @author Peng
 * @since 2021-10-12
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    SysMenuMapper sysMenuMapper;
    @Autowired
    SysModuleMapper moduleMapper;
    @Autowired
    PubReportMapper pubReportMapper;

    @Transactional
    public Result addMenu(SysMenu sysMenu){
        Map returnMap = new HashMap<>();
        SysUser sysUser =  RedisUserManager.getUser();
        if(StringUtils.isNotBlank(sysUser.getOrgId())){
            sysMenu.setOrgId(sysUser.getOrgId());
        }
        sysMenu.setIsAssembly("0");
        sysMenu.setIsCommonUse("0");
        sysMenu.setIsDictMenu("0");
        sysMenu.setIsReport("0");
        sysMenu.setIsTool("0");
        sysMenu.setCode(IncrementalNumberGenerator.generateIncrementalNumber5());
        sysMenuMapper.insert(sysMenu);
        String id = sysMenu.getId();
        if( ToolsUtils.isNotEmpty(sysMenu.getIsReport())&&sysMenu.getIsReport().equals("0")) {
            if (ToolsUtils.isNotEmpty(sysMenu.getReportId())) { //根据选中的模版设置当前菜单下的模版启用标记
                LambdaUpdateWrapper<PubReport> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.set(PubReport::getIsUse, "1").eq(PubReport::getType, "1").eq(PubReport::getMenuId,id);
                pubReportMapper.update(null, lambdaUpdateWrapper);
                PubReport pubReport = new PubReport();
                pubReport.setId(sysMenu.getReportId());
                pubReport.setIsUse("0");
                pubReportMapper.updateById(pubReport);
            }
        }
        returnMap.put("healthCheckId", id);
        return Result.succ(1,"添加菜单成功",returnMap);
    }
    @Transactional
    public Result editMenu(SysMenu sysMenu){
        Map returnMap = new HashMap<>();
        this.baseMapper.updateById(sysMenu);
           if( ToolsUtils.isNotEmpty(sysMenu.getIsReport())&&sysMenu.getIsReport().equals("0")){
                if(ToolsUtils.isNotEmpty(sysMenu.getReportId())){ //根据选中的模版设置当前菜单下的模版启用标记
                    LambdaUpdateWrapper<PubReport> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    lambdaUpdateWrapper.set(PubReport::getIsUse, "1").eq(PubReport::getType, "1").eq(PubReport::getMenuId,sysMenu.getId());
                    pubReportMapper.update(null, lambdaUpdateWrapper);
                    PubReport pubReport = new PubReport();
                    pubReport.setId(sysMenu.getReportId());
                    pubReport.setIsUse("0");
                    pubReportMapper.updateById(pubReport);
                }
           }
        returnMap.put("menu", sysMenu);
        return Result.succ(1,"修改菜单成功",returnMap);
    }

    public Result deleteMenu(String id){
        //删除此菜单时先查看一下是否有角色存在此菜单
        MPJLambdaWrapper<SysRoleMenu> lambdaQueryWrapper = new MPJLambdaWrapper<>();
        lambdaQueryWrapper.selectAll(SysRoleMenu.class);
        lambdaQueryWrapper.leftJoin(SysRole.class,SysRole::getId,SysRoleMenu::getRoleId);
        lambdaQueryWrapper.eq(SysRole::getDelFlag,0);
        lambdaQueryWrapper.eq(SysRoleMenu::getMenuId,id).eq(SysRoleMenu::getDelFlag,0);
        List<SysRoleMenu> list = sysRoleMenuMapper.selectList(lambdaQueryWrapper);
        SysMenu sysMenuUp =  sysMenuMapper.selectById(id);
        if(ToolsUtils.isNotEmpty(list)){
            return Result.fail("有角色在使用此菜单，删除失败");
        }else {
            //删除此菜单时先查看一下是否有子菜单
            LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysMenu::getDelFlag,0).eq(SysMenu::getParentId,id);
            Integer count = sysMenuMapper.selectCount(queryWrapper);
            if(count>0){
                return Result.fail("此菜单下有子菜单，删除失败");
            }
            sysMenuUp.setDelFlag(1);
            int deleteById = sysMenuMapper.updateById(sysMenuUp);
            if(deleteById>0){
                Map<String,Object> resultMap = new HashMap<>();
                resultMap.put("menuId",id);
                return  Result.succ(1,"删除成功",resultMap);
            }else{
                return Result.fail("删除失败");
            }
        }
    }

    @Override
    public Result findMenuList(SysMenu sysMenu) {
        Map map = new HashMap();
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getDelFlag,0);
        if(StringUtils.isNotBlank(sysMenu.getModuleId())){
            queryWrapper.eq(SysMenu::getModuleId, sysMenu.getModuleId());
        }
        queryWrapper.orderByAsc(SysMenu::getSn);
        List<SysMenu> menuList = sysMenuMapper.selectList(queryWrapper);
        List<String> rptIds = menuList.stream().filter(a -> StringUtils.isNotBlank(a.getReportId())).map(SysMenu::getReportId).distinct().collect(Collectors.toList());
        if(CollectionUtils.isNotEmpty(rptIds)){
            List<PubReport> reportList = pubReportMapper.selectBatchIds(rptIds);
            if(CollectionUtils.isNotEmpty(reportList)){
                for(SysMenu menu: menuList){
                    Optional<PubReport> first = reportList.stream().filter(r -> r.getId().equals(menu.getReportId())).findFirst();
                    if(StringUtils.isNotBlank(menu.getReportId())){
                        if(first.isPresent()){
                            menu.setReportName(first.get().getName());
                        }
                    }
                }

            }
        }
        List<SysMenu> returnList = new ArrayList<>();
        menuList.forEach(a -> {
            if (StringUtils.isBlank(a.getParentId())) {
                //a.put("children", this.getChildren(a, menuList));
                a.setChildren(this.getChildren(a, menuList));
                returnList.add(a);
            }
        });
        map.put("menuList", returnList);
        return Result.succ(1, "成功", map);
    }

    @Override
    public Result getMenuListByType(SysMenu sysMenu) {
        Map map = new HashMap();
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getDelFlag,0).eq(SysMenu::getIsReport,0);
        queryWrapper.orderByAsc(SysMenu::getSn);
        List<SysMenu> menuList = sysMenuMapper.selectList(queryWrapper);
        map.put("menuList",menuList);
        return Result.succ(1, "成功", map);
    }

    @Override
    public Result getModuleAndMenuList(SysMenu menuReq) {
        LambdaQueryWrapper<SysModule> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(SysModule::getDelFlag, 0);
        lambdaQueryWrapper.orderByAsc(SysModule::getSn);
        List<SysModule> modules = moduleMapper.selectList(lambdaQueryWrapper);

        LambdaQueryWrapper<SysMenu> pointsLambdaQueryWrapper = new LambdaQueryWrapper();

        pointsLambdaQueryWrapper.eq(SysMenu::getDelFlag, 0);
        if(ToolsUtils.isNotEmpty(menuReq.getIsReport())){
            pointsLambdaQueryWrapper.eq(SysMenu::getIsReport,menuReq.getIsReport());
        }
        pointsLambdaQueryWrapper.orderByAsc(SysMenu::getSn);
        List<SysMenu> menuList = sysMenuMapper.selectList(pointsLambdaQueryWrapper);

        Map<String, ModuleAndMenuTreeVo> moduleMap = new LinkedHashMap<>();
        if (ToolsUtils.isNotEmpty(modules)) {
            // 遍历 modules 列表，将 SysModule 对象转换为 ModuleAndPointTreeVo 对象，并放入 moduleMap 中
            for (SysModule module : modules) {
                ModuleAndMenuTreeVo moduleAndMunuTreeVo = new ModuleAndMenuTreeVo();
                moduleAndMunuTreeVo.setId(module.getId());
                moduleAndMunuTreeVo.setTitle(module.getName());
                moduleAndMunuTreeVo.setIcon(module.getIcon());
                moduleAndMunuTreeVo.setType("module");
                moduleAndMunuTreeVo.setChildren(new ArrayList<>());
                moduleMap.put(module.getId(), moduleAndMunuTreeVo);
            }

            // 遍历 pointsList 列表，将 SysPoints 对象转换为 ModuleAndPointTreeVo 对象，并添加到对应的父节点下
            if (ToolsUtils.isNotEmpty(menuList)) {
//                for (SysMenu menu : menuList) {
//                    ModuleAndMenuTreeVo menuTreeVo = new ModuleAndMenuTreeVo();
//                    menuTreeVo.setId(menu.getId());
//                    menuTreeVo.setTitle(menu.getTitle());
//                    menuTreeVo.setIcon(menu.getIcon());
//                    ModuleAndMenuTreeVo moduleAndMenu = moduleMap.get(menu.getModuleId());
//                    if (moduleAndMenu != null) {
//                        if (moduleAndMenu.getChildren() == null) {
//                            moduleAndMenu.setChildren(new ArrayList<>());
//                        }
//                        moduleAndMenu.getChildren().add(menuTreeVo);
//                    }
//                }

                //先把父节点为空的找出来
                List<SysMenu> parentNullList = menuList.stream().filter(a -> StringUtils.isBlank(a.getParentId())).collect(Collectors.toList());
                for(SysMenu menu : parentNullList){
                    ModuleAndMenuTreeVo menuTreeVo = new ModuleAndMenuTreeVo();
                    menuTreeVo.setId(menu.getId());
                    menuTreeVo.setTitle(menu.getTitle());
                    menuTreeVo.setIcon(menu.getIcon());
                    menuTreeVo.setModuleId(menu.getModuleId());
                    menuTreeVo.setType("menu");
                    ModuleAndMenuTreeVo moduleAndMenu = moduleMap.get(menu.getModuleId());
                    if (moduleAndMenu != null) {
                        if (moduleAndMenu.getChildren() == null) {
                            moduleAndMenu.setChildren(new ArrayList<>());
                        }
                        moduleAndMenu.getChildren().add(menuTreeVo);
                    }
                    //取出这个menu下的所有menu
                    List<SysMenu> childrenList = menuList.stream().filter(a -> StringUtils.isNotBlank(a.getParentId()) && a.getParentId().equals(menu.getId())).collect(Collectors.toList());
                    if(ToolsUtils.isNotEmpty(childrenList)){
                        if (menuTreeVo.getChildren() == null) {
                            menuTreeVo.setChildren(new ArrayList<>());
                        }
                        for(SysMenu childrenmenu : childrenList){
                            ModuleAndMenuTreeVo childrenmenuTreeVo = new ModuleAndMenuTreeVo();
                            childrenmenuTreeVo.setId(childrenmenu.getId());
                            childrenmenuTreeVo.setTitle(childrenmenu.getTitle());
                            childrenmenuTreeVo.setIcon(childrenmenu.getIcon());
                            childrenmenuTreeVo.setModuleId(childrenmenu.getModuleId());
                            childrenmenuTreeVo.setType("menu");
                            menuTreeVo.getChildren().add(childrenmenuTreeVo);
                        }
                    }
                }
            }

        }
        List<ModuleAndMenuTreeVo> ListTree = new ArrayList<>(moduleMap.values());
        return Result.succ(ListTree);
    }

    @Override
    public String  selectDeleteMenu(String code) {
        //删除此菜单时先查看一下是否有角色存在此菜单
        LambdaQueryWrapper<SysRoleMenu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<SysMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysMenu::getCode,code);
        SysMenu sysMenuDe =  sysMenuMapper.selectOne(queryWrapper);
        if(ToolsUtils.isNotEmpty(sysMenuDe)){
            String id = sysMenuDe.getId();
            lambdaQueryWrapper.eq(SysRoleMenu::getMenuId,id).eq(SysRoleMenu::getDelFlag,'0');
            Integer selectCount = sysRoleMenuMapper.selectCount(lambdaQueryWrapper);
            SysMenu sysMenuUp =  sysMenuMapper.selectById(id);
            if(selectCount>0){
                return "有角色在使用此菜单，删除失败";
            }else {
                //删除此菜单时先查看一下是否有子菜单
                LambdaQueryWrapper<SysMenu> queryWrapperChiend = new LambdaQueryWrapper<>();
                queryWrapperChiend.eq(SysMenu::getDelFlag,0).eq(SysMenu::getParentId,id);
                Integer count = sysMenuMapper.selectCount(queryWrapperChiend);
                if(count>0){
                    return "此菜单下有子菜单，删除失败";
                }

            }
        }
        return "1";
    }

    public List<SysMenu> getChildren(SysMenu a, List<SysMenu> menuList) {
        List<SysMenu> result = new ArrayList();
        for (SysMenu menu : menuList) {
            if (StringUtils.isBlank(menu.getParentId())) {
                menu.setParentName("");
            }

            if (StringUtils.isNotBlank( menu.getParentId()) && menu.getParentId().equals(a.getId())) {
                menu.setParentName(a.getTitle());
                result.add(menu);
            }

        }
        for (SysMenu menu : result) {
            menu.setChildren(getChildren(menu, menuList));
        }
        if (result.size() == 0) {
            return new ArrayList<>();
        }
        return result;

    }
    public List<SysMenu> getSysMenusByRoleId(String roleId){
        MPJLambdaWrapper<SysMenu> menuByRoleIdWrapper = new MPJLambdaWrapper<>();
        menuByRoleIdWrapper
                .distinct()
                .selectAll(SysMenu.class)
                .leftJoin(SysRoleMenu.class, SysRoleMenu::getMenuId, SysMenu::getId)
                .eq(SysMenu::getDelFlag, "0")
                .eq(SysRoleMenu::getRoleId, roleId)
                .orderByAsc(SysMenu::getSn);
        List<SysMenu> sysMenus = sysMenuMapper.selectList(menuByRoleIdWrapper);
        return sysMenus;
    }
}
